其他
萌新逆向学习笔记——CreateRemoteThread注入Shellcode
本文为看雪论坛优秀文章
看雪论坛作者ID:psycongroo
前言
原理
DWORD WINAPI ThreadProc(
_In_ LPVOID lpParameter
);
typedef struct _INJECT_DATA
{
char lpText[8]; //参数1
char lpCaption[8]; //参数2
}INJECT_DATA;
typedef struct _INJECT_DATA
{
BYTE shellCode[0x1D]; //一段ShellCode执行MessageBoxA
char lpText[8]; //message
char lpCaption[8]; //title
LPVOID lpThreadStart; //MessageBoxA地址
}INJECT_DATA;
__declspec (naked)
void shellCodeFun(void) {
__asm {
call L001;
L001:
pop ebx;
//sub ebx, 5;
and bx, 0;
push 0;
lea esi, dword ptr ds : [ebx]INJECT_DATA.lpCaption ; //0x25注意偏移量
push esi;
lea esi, dword ptr ds : [ebx]INJECT_DATA.lpText ; //0x1D
push esi;
push 0;
call dword ptr ds : [ebx]INJECT_DATA.lpThreadStart ; //0x2D
ret;
}
}
实践
步骤一定义和初始化:
INJECT_DATA data;
ZeroMemory(&data, sizeof(INJECT_DATA));
PBYTE pShellCode = (PBYTE)shellCodeFun;
#ifdef DEBUG
if (pShellCode[0] == 0xE9)
{
//debug环境下会多一个jmp xxxx指令,必须拿到xxxx地址,地址大小为5字节
//因为jump xxxx,这个xxxx为相对地址,所以为 目前地址+xxxx地址+整个jmp指令长度
pShellCode = pShellCode + *(ULONG*)(pShellCode + 1) + 5;
}
#endif // DEBUG
memcpy(data.shellCode, pShellCode, sizeof(data.shellCode));
char text[] = "message";
char title[] = "title";
memcpy(data.lpText, text, 8);
memcpy(data.lpCaption, title, 8);
/*data.lpText = text;
data.lpCaption = title;*/ //值一定要在目标进程空间内
HMODULE hmod = GetModuleHandleA("user32.dll");
FARPROC dialog = GetProcAddress(hmod, "MessageBoxA");
data.lpThreadStart = dialog;
call L001; //自己是为了自定位,为了拿到Shellcode开始的地址,也即是结构体的地址。
L001:
pop ebx; //拿出call时保存的返回地址
and bx, 0; //因为使用VirtualAllocEx函数申请的虚拟内存都是64kb对齐的,只要低地址。
push 0;
lea esi, dword ptr ds : [ebx]INJECT_DATA.lpCaption ;
....
#ifdef DEBUG
if (pShellCode[0] == 0xE9)
{
//debug环境下会多一个jmp xxxx指令,必须拿到xxxx地址,地址大小为5字节
//因为jump xxxx,这个xxxx为相对地址,所以为 目前地址+xxxx地址+整个jmp指令长度
pShellCode = pShellCode + *(ULONG*)(pShellCode + 1) + 5;
}
#endif // DEBUG
步骤二申请内存并写入:
int injectSize = sizeof(INJECT_DATA);
PBYTE mBuffer = (PBYTE)VirtualAllocEx(mProcess, NULL, injectSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE); //注意要为 PAGE_EXECUTE_READWRITE
WriteProcessMemory(mProcess, mBuffer, &data, injectSize, NULL)
步骤三建立远程线程执行:
mRemoteThread = CreateRemoteThread(mProcess, NULL, 0, (LPTHREAD_START_ROUTINE)mBuffer, NULL, 0, NULL);
总结
附加说明
第一条:使用调试器调试
第二条Shellcode自定位
第三条debug版本中Shellcode地址处理
#ifdef DEBUG
if (pShellCode[0] == 0xE9)
{
//debug环境下会多一个jmp xxxx指令,必须拿到xxxx地址,地址大小为5字节
//因为jump xxxx,这个xxxx为相对地址,所以为 目前地址+xxxx地址+整个jmp指令长度
pShellCode = pShellCode + *(ULONG*)(pShellCode + 1) + 5;
}
#endif // DEBUG
附件
看雪ID:psycongroo
https://bbs.pediy.com/user-home-899080.htm
*本文由看雪论坛 psycongroo 原创,转载请注明来自看雪社区。
扫码购票立享2.5折优惠!
十大干货议题收入囊中!
推荐文章++++
求分享
求点赞
求在看